NewHandle
NewHandle
Allocate relocatable block from current heap zone Size dataSize ; desired size for the data (a 32-bit value) returns handle leading to allocated area; NIL if can't
NewHandle is the generic memory allocation tool for obtaining blocks of relocatable memory.
dataSize is the desired size for the allocated data area. The allocated block
actually occupies up to 12 bytes more than dataSize .
Returns: a generic Handle (a pointer to a pointer to a data area; officially, Handle is a typedef for char **). If the area cannot be allocated, the return value is NIL (0).
Notes: NewHandle makes every effort to allocate the requested memory, including compacting the heap, increasing its size, purging purgeable
blocks, and calling its grow function, if any (see SetGrowZone). Initially, all allocated handles are unlocked (moveable) and un purgeable.
The returned Handle is a pointer to a "master pointer" (which actually points to the data area). Should the block be moved, the value of the Handle remains the same, but its master pointer will change.
All Macintosh Handle values are instances of double in direction. To access the area allocated by this call, you can "de reference" the handle. For
instance:
myHandle = NewHandle( 1024 ); /* allocate 1K bytes */ myDataPtr = * myHandle; [TOKEN:12074] de reference: get addr of data */
*myDataPtr = 1; [TOKEN:12074] store a value */
c = myDataPtr[900]; [TOKEN:12074] read a value */
For allocating an instance of a structure, you will need to coerce the
returned value into the desired data type. Then, there are several ways to
access the data, e.g.:
typedef MyStruct **StructHandle;
struct MyStruct *myStructPtr;
StructHandle myHandle;
myHandle = (StructHandle)NewHandle( sizeof (MyStruct) ); x = (* myHandle)->myField; /* is the same as ... */
x = (** myHandle).myField;
myStructPtr = * myHandle; /* dereference (get addr of data) */
x = myStructPtr->myField; /* is the same as ... */
x = (*myDataPtr).myField;
Locking Handles
Many Toolbox and OS calls can cause a relocatable block to be moved (as
well as calls to functions in unloaded segments), thus, you should NEVER
rely on a de referenced pointer to remain valid for any length of time. For
any extensive access, you must lock a handle:
HLock( myHandle ); [TOKEN:12074] keep it from moving */ .
... access the data ...
.
HUnlock( myHandle ); [TOKEN:12074] let it move freely */ expand the allocation via SetHandleSize. You should unlock the handle more on determining when memory may move.
You can allocate non-relocatable data areas with NewPtr. However, this can cause the heap to become fragmented, making it impossible to get the
maximum useable storage from available RAM.
returns the address of a NIL master pointer, without actually allocating any
memory.